#include <riscv/print.h>

namespace riscv {

  Print::Print(std::ostream & _out) : out(_out) {}

  void Print::print(CompUnit & comp_uint) {
    for(Global * global : comp_uint.global_list) {
      this->out << ".text\n";
      this->out << ".global " << global->name << "\n";
      this->out << ".data\n";
      this->out << ".align 2\n";
      this->out << ".type " << global->name << ", @object\n";
      this->out << ".size " << global->name << ", " << global->size << "\n";
      this->out << global->name << ":\n";
      this->out << ".word " << global->init_number << "\n";
    }
    this->out << ".text\n";
    for(Func * func : comp_uint.func_list) {
      this->out << ".align 1\n";
      this->out << ".global " << func->name << "\n";
      this->out << ".type " << func->name << ", @function\n";
      this->out << func->name << ":\n";
      this->out << func->block_begin->get_name() << ":\n";
      for(Inst * inst : func->block_begin->inst_list) {
        this->out << "\t" << inst->get_str() << "\n";
      }
      for(Block * block : func->block_list) {
        this->out << block->get_name() << ":\n";
        for(Inst * inst : block->inst_list) {
          this->out << "\t" << inst->get_str() << "\n";
        }
      }
      this->out << func->block_end->get_name() << ":\n";
      for(Inst * inst : func->block_end->inst_list) {
        this->out << "\t" << inst->get_str() << "\n";
      }
      this->out << ".size " << func->name << ", .-" << func->name << "\n";
    }
    this->out << ".section .rodata\n";
    for(FloatNumber * float_number : comp_uint.float_list) {
      this->out << ".align 2\n";
      this->out << float_number->get_name() << ":\n";
      this->out << ".float " << std::to_string(float_number->get_number()) << "\n";
    }
  }
}
